CONTENTS | INDEX | PREV | NEXT
LockAddr
LockAddrB
TryLockAddr
TryLockAddrB
UnlockAddr
UnlockAddrB
NAME
LockAddr - Gain Exclusive, Fast semaphore (bit 0)
LockAddrB - Gain Exclusive, Fast semaphore (bit n 0-7)
TryLockAddr - Non-Blocking version of LockAddr
TryLockAddrB - Non-Blocking version of LockAddrB
UnlockAddr - Release exclusive semaphore, bit 0
UnlockAddrB - Release exclusive semaphore, bit n 0-7
SYNOPSIS
void LockAddr(lck);
void LockAddrB(bitno, lck);
int r = TryLockAddr(lck);
int r = TryLockAddrB(bitno, lck);
void UnlockAddr(lck);
void UnlockAddrB(bitno, lck);
long lck[2];
FUNCTION
These are custom DICE functions used for inter-task locking semaphores
in programs that need such functions. These routines are somewhat
faster than standard Amiga semaphore routines and take less memory,
though at the cost of DICE specific.
To use an inter-task lock one first initializes an lck array to
0's. long lck[2]; is an array of two longwords that the lock
routines will use to perform their stuff. This array should be
zero'd only once at program initialization time (the master task
before any other tasks are created that use it).
Each lck array may hold up to 8 locks, hence the LockAddrB() calls.
The non-B calls use lock #0 for simplicity. For simplicity we
will only discuss non-B calls. To gain a lock you may call
LockAddr() with the address of the lck array (which, being an array,
does not need the & in the call). This routine will not return
until the lock can be obtained.
You may also use TryLockAddr() to attempt to gain a lock. The
return value is:
-1 Unable to obtain the lock, it is in use
1 Lock obtained
To release an obtained lock you call UnlockAddr(lck). DO NOT RELEASE
A LOCK YOU DO NOT HAVE!
EXAMPLE
/*
* This program obtains a lock based at a public message port and
* holds it for ten seconds before releasing it. The public message
* port is left in memory (but only exists once no matter how many
* programs you run).
*
* To test locking, open up two or more CLI's and run the program
* simultaniously (or as close as your fingers can make it) two or
* more times. Only one program will 'have' the lock at a time.
*
* we use AllocMem() so the port survives the program
*/
#include <exec/types.h>
#include <exec/ports.h>
#include <exec/memory.h>
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
typedef struct {
struct MsgPort Port;
long Lock[2];
} MyPort;
extern void *FindPort();
extern void *CreatePort();
extern void *AllocMem();
MyPort *Port;
short HaveLock;
int
brk()
{
if (HaveLock)
UnlockAddr(Port->Lock);
return(1); /* abort */
}
main()
{
char *portName = "Lock-Test";
onbreak(brk);
Forbid();
if ((Port = FindPort(portName)) == NULL) {
MyPort *port;
port = AllocMem(sizeof(MyPort) + strlen(portName) + 1, MEMF_PUBLIC | MEMF_CLEAR);
assert(port);
port->Port.mp_Node.ln_Name = (char *)(port + 1);
port->Port.mp_Node.ln_Type = NT_MSGPORT;
strcpy(port->Port.mp_Node.ln_Name, portName);
AddPort(port);
Port = port;
}
Permit();
puts("getting lock");
LockAddr(Port->Lock);
HaveLock = 1;
puts("Got the lock!, sleeping for 10 seconds");
sleep(10);
UnlockAddr(Port->Lock);
HaveLock = 0;
puts("released lock");
return(0);
}
INPUTS
long *lck; A pointer to two longwords, initially zero'd
int bitno; lock # ... up to 8 independant locks exist for
each lck structure
RESULTS
int r; (TryLock only), -1 on failure, 1 on success.
SEE ALSO